<?php

namespace app\common\controller;
use think\facade\Db;
use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
use WechatPay\GuzzleMiddleware\Validator;

/**
 * Class SrapiUserController
 * @package app\common\controller
 */
class SrapiUserController extends SrapiController
{
    public function initialize()
    {
        parent::initialize();
        if(empty($this->userId)){
            $this->userId = $this->getUserId();
        }
    }
    
    
    // 支付下单
    public function payV3($out_trade_no, $openid, $pay, $notify){
        $merchantId = sysconfig('wxapp','mchid');
        $merchantSerialNumber = sysconfig('wxapp','serial_num');
        $merchantPrivateKey = PemUtil::loadPrivateKey('cert/apiclient_key.pem');
        $wechatpayCertificate = PemUtil::loadCertificate('cert/cert.pem');
        $wechatpayMiddleware = WechatPayMiddleware::builder()
            ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
            ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书，参数类型为array
            ->build();
        $stack = \GuzzleHttp\HandlerStack::create();
        $stack->push($wechatpayMiddleware, 'wechatpay');
        
        $client = new \GuzzleHttp\Client(['handler' => $stack]);
        try {
            $response = $client->request('POST', 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi',[
                'headers' => [ 'Accept' => 'application/json' ],
                'json' => [ // JSON请求体
                    'appid' => sysconfig('wxapp','app_id'),
                    'mchid' => $merchantId,
                    'description' => '支付订单',
                    'out_trade_no' => $out_trade_no,
                    'notify_url' => 'https://'.$_SERVER['HTTP_HOST'].$notify,
                    'amount' => [
                        'total' => intval($pay * 100)
                    ],
                    'payer' => [
                        'openid' => $openid
                    ]
                ]
            ]);
        } catch (RequestException $e) {
            $body = json_decode($e->getResponse()->getBody(),true);
            $this->error($body['code'].' '.$body['message']);
        }
        if($response->getStatusCode() == 200){
            $body = json_decode($response->getBody(),true);
            $jsApiParameters = $this->GetJsApiParameters($body['prepay_id']);
            return $jsApiParameters;
        }
    }
    
    // 生成支付参数
    public function GetJsApiParameters($prepay_id){
        $timeStamp = time();
        $nonceStr = $this->getNonceStr();
        $mch_private_key = PemUtil::loadPrivateKey('cert/apiclient_key.pem');
        $package = 'prepay_id='.$prepay_id;
        $string = sysconfig('wxapp','app_id')."\n".
            "$timeStamp"."\n".
            $nonceStr."\n".
            $package."\n";
        openssl_sign($string, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
        $paySign = base64_encode($raw_sign);
        return ['timeStamp'=>"$timeStamp",'nonceStr'=>$nonceStr,'package'=>$package,'signType'=>'RSA','paySign'=>$paySign];
    }


    public static function getNonceStr($length = 32) 
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {  
            $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
        } 
        return $str;
    }
    
    /**
     * 获取惟一订单号
     * @return string
     */
    function get_order_sn()
    {
        return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }

    public function refundV3($out_trade_no, $out_refund_no, $total, $refund_money){
        $merchantId = sysconfig('wxapp','mchid');
        $merchantSerialNumber = sysconfig('wxapp','serial_num');
        $merchantPrivateKey = PemUtil::loadPrivateKey('cert/apiclient_key.pem');
        $wechatpayCertificate = PemUtil::loadCertificate('cert/cert.pem');
        $wechatpayMiddleware = WechatPayMiddleware::builder()
            ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
            ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书，参数类型为array
            ->build();
        $stack = \GuzzleHttp\HandlerStack::create();
        $stack->push($wechatpayMiddleware, 'wechatpay');
        
        $client = new \GuzzleHttp\Client(['handler' => $stack]);
        try {
            $response = $client->request('POST', 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds',[
                'headers' => [ 'Accept' => 'application/json' ],
                'json' => [ // JSON请求体
                    'out_trade_no' => $out_trade_no,
                    'out_refund_no' => $out_refund_no,
                    'amount' => [
                        'total' => intval($total * 100),
                        'refund' => intval($refund_money * 100),
                        'currency' => 'CNY'
                    ]
                ]
            ]);
        } catch (RequestException $e) {
            $body = json_decode($e->getResponse()->getBody(),true);
            $this->error($body['code'].' '.$body['message']);
        }
        if($response->getStatusCode() == 200){
            $body = json_decode($response->getBody(),true);
            echo '<pre>';print_r($body);
        }
    }
}

